﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ciloci.Flee;
using OpenExpressApp.Module.Library.Security;
using OpenExpressApp.MetaAttribute;
using OpenExpressApp.OpenException;
using OpenExpressApp.MetaModel;

namespace OpenExpressApp.Expression
{
    public class DataPermissionExprParser : ObjectExprParser
    {
        string mergedExpr;
        bool needCheckOrg = false;
        public DataPermissionExprParser(object owner)
            : base(owner)
        {
            needCheckOrg = null != owner.GetType().GetProperty(DBConvention.FieldName_Orgid);
            Guid businessObjectId = new Guid(owner.GetType().GetSingleAttribute<BusinessObjectAttribute>().Id);
            string[] exprs = (Csla.ApplicationContext.User.Identity as OEAIdentity).GetDataPermissionExpr(businessObjectId);
            if (exprs.Length == 0)
                mergedExpr = String.Empty;
            else if (exprs.Length == 1)
                mergedExpr = exprs[0];
            else
            { 
                mergedExpr = string.Join(") OR (", exprs);
                mergedExpr = String.Format("({0})", mergedExpr);
            }
            if (String.Empty != mergedExpr)
            {
                try
                {
                    //替换\为\\
                    mergedExpr = mergedExpr.Replace("\\", "\\\\");
                    Compile(mergedExpr);
                }
                catch (Exception ex)
                {
                    throw new ExpressionException(String.Format("表达式{0}错误:{1}", mergedExpr, ex.Message));
                }
            }
        }

        public bool CanRead(object owner)
        {
            //默认支持组织权限
            bool haveRightOnOrg = true;
            if (needCheckOrg)
            {
                Guid? orgId = owner.GetPropertyValue<Guid?>(DBConvention.FieldName_Orgid);
                if (null != orgId) haveRightOnOrg = (Csla.ApplicationContext.User.Identity as OEAIdentity).HavePermissionOnOrg((Guid)(orgId.Value));
            }
            return (String.IsNullOrEmpty(mergedExpr) || (bool)Evaluate(owner)) && haveRightOnOrg;
        }
    }
}
